

package ws.very.util.mapdb.akka.wraper

import akka.actor.Actor
import ws.very.util.akka.actor.ReplyAct
import akka.event.Logging
import akka.actor.ActorLogging
import org.{ mapdb => md }
import ws.very.util.akka.io.TmpFileDesc
import java.io.File
import scala.util.Try
import ws.very.util.akka.io.FullFileDesc

class AkkaWrapper extends Actor with ReplyAct with ActorLogging {
  val dbCache = scala.collection.mutable.Map[S, md.DB]()
  
  

  protected def dbRefTo[R](dbName: S)(dbToDo: md.DB => S | R): S | R =
    dbCache.get(dbName).map { db =>
      dbToDo(db)
    }.getOrElse(Left("db ref not exists"))
  def receive: Receive = {
    //FIXME:管理不统一
    case (dbName: S,
      dbMaker @ DbMaker(
        makeEngine @ MakeEngine(store, snapshot, fullTx, closeOnJvmShutdown, cache), strictDBGet)) =>
      tryReply {
        val db = store match {
          case file: Store.File =>
            md.DBMaker.newFileDB(file.file match {
              case TmpFileDesc(prefix, suffix) =>
                File.createTempFile(prefix, suffix)
              case FullFileDesc(filePath) =>
                new File(filePath)
            })
        }
        if (closeOnJvmShutdown) db.closeOnJvmShutdown()

        val result = db.make
        dbCache += (dbName -> result)

        true
      }
    case (dbName: S, dbCmd: DB.Cmd) => tryReply {
      dbRefTo(dbName) { db =>
        Right(db.commit())
      }
    }
    case (dbName: S, maker: BTreeMapMaker[_, _]) => tryReply {
      dbRefTo(dbName) { db =>
        db.createTreeMap(maker.name)
        Right(true)
      }
    }
    case (dbName: S, collName: S, act: BTreeMap.Cmd) => tryReply {
      dbRefTo(dbName) { db =>
        val coll = db.getTreeMap[A, A](collName)
        Right(
          act match {
            case BTreeMap.Get(key)  => coll.get(key)
            case BTreeMap.Put(k, v) => coll.put(k, v)
          })
      }
    }
  }
}